home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / 68hc11 / smallc11.arc / CC13.C < prev    next >
Text File  |  1988-05-27  |  8KB  |  351 lines

  1. /*
  2. ** statement parser
  3. **
  4. ** called whenever syntax requires a statement
  5. **  this routine performs that statement
  6. **  and returns a number telling which one
  7. */
  8. statement() {
  9.   if ((ch==0) & (eof)) return;
  10.   else if(amatch("char",4)) {
  11.     declloc(CCHAR);
  12.     ns();
  13.     }
  14.   else if(amatch("int",3)) {
  15.     declloc(CINT);
  16.     ns();
  17.     }
  18.   else {
  19.     if(declared >= 0) {
  20.       if(ncmp > 1) nogo=declared; /* disable goto if any */
  21.       csp=modstk(csp - declared, NO);
  22.       declared = -1;
  23.       }
  24.     if(match("{")) compound();
  25.     else if(amatch("if",2)) {
  26.       doif();
  27.       lastst=STIF;
  28.       }
  29.     else if(amatch("while",5)) {
  30.       dowhile();
  31.       lastst=STWHILE;
  32.      }
  33. #ifdef STDO
  34.     else if(amatch("do",2)) {
  35.       dodo();
  36.       lastst=STDO;
  37.       }
  38. #endif
  39. #ifdef STFOR
  40.     else if(amatch("for",3)) {
  41.       dofor();
  42.       lastst=STFOR;
  43.       }
  44. #endif
  45. #ifdef STSWITCH
  46.     else if(amatch("switch",6)) {
  47.       doswitch();
  48.       lastst=STSWITCH;
  49.       }
  50.     else if(amatch("case",4)) {
  51.       docase();
  52.       lastst=STCASE;
  53.       }
  54.     else if(amatch("default",7)) {
  55.       dodefault();
  56.       lastst=STDEF;
  57.       }
  58. #endif
  59. #ifdef STGOTO
  60.     else if(amatch("goto",4)) {
  61.       dogoto();
  62.       lastst=STGOTO;
  63.       }
  64.     else if(dolabel()) ;
  65. #endif
  66.     else if(amatch("return",6)) {
  67.       doreturn();
  68.       ns();
  69.       lastst=STRETURN;
  70.       }
  71.     else if(amatch("break",5)) {
  72.       dobreak();
  73.       ns();
  74.       lastst=STBREAK;
  75.       }
  76.     else if(amatch("continue",8)) {
  77.       docont();
  78.       ns();
  79.       lastst=STCONT;
  80.       }
  81.     else if(match(";")) errflag=0;
  82.     else if(match("#asm")) {
  83.       doasm();
  84.       lastst=STASM;
  85.       }
  86.     else {
  87.       doexpr();
  88.       ns();
  89.       lastst=STEXPR;
  90.       }
  91.     }
  92.   return lastst;
  93.   }
  94.  
  95. compound()  {
  96.  
  97.   int savcsp;
  98.   char *savloc;
  99.   savcsp = csp;
  100.   savloc = locptr;
  101.   declared = 0;     /* may now declare local variables    */
  102.   ++ncmp;        /* new level open        */
  103.   while(match("}") == 0) {
  104.     if(eof) {
  105.       error("no final }");
  106.       break;
  107.       }
  108.     else statement();         /* do one     */
  109.     }
  110.   --ncmp;             /* close current level */
  111.   csp = modstk(savcsp, NO);  /* delete local variable space */
  112. #ifdef STGOTO
  113.   cptr = savloc;        /* retain labels  */
  114.   while(cptr < locptr) {
  115.     cptr2 = nextsym(cptr);
  116.     if(cptr[IDENT] == LABEL) {
  117.       while(cptr < cptr2)
  118.     *savloc++ = *cptr++;
  119.       }
  120.     else cptr = cptr2;
  121.     }
  122. #endif
  123.   locptr = savloc;     /* delete local symbols */
  124.   declared = -1;       /* may not declare variables  */
  125.   }
  126.  
  127. doif()    {
  128.   int       flab1,flab2;
  129.   flab1 = getlabel();  /* get label for false branch */
  130.   test(flab1, YES);    /* get expression, & branch false */
  131.   statement();           /* if true do a statement */
  132.   if(amatch("else",4) == 0) {       /* if...else ? */
  133.     /* simple if ..print false label */
  134.     postlabel(flab1);
  135.     return;          /* and exit */
  136.     }
  137.   flab2 = getlabel();
  138. #ifdef     STGOTO
  139.   if ((lastst != STRETURN) & (lastst != STGOTO))
  140.     jump(flab2);
  141. #else
  142.   if(lastst != STRETURN)
  143.     jump(flab2);
  144. #endif
  145.   postlabel(flab1);    /* print false label */
  146.   statement();           /* and do "else" clause   */
  147.   postlabel(flab2);    /* print true label     */
  148.   }
  149.  
  150. doexpr()  {
  151.   int const1,val;
  152.   char *before,*start;
  153.   while(1) {
  154.     setstage(&before, &start);
  155.     expression(&const1, &val);
  156.     clearstage(before, start);
  157.     if(ch != ',')  break;
  158.     bump(1);
  159.     }
  160.   }
  161.  
  162. dowhile() {
  163.   int wq[4];          /* allocate local queue */
  164.   addwhile(wq);       /* add entry to queu for break */
  165.   postlabel(wq[WQLOOP]);   /* loop label */
  166.   test(wq[WQEXIT], YES);  /* see if true */
  167.   statement();          /* if so, do a statement */
  168.   jump(wq[WQLOOP]);      /* loop to label */
  169.   postlabel(wq[WQEXIT]);  /* exit label */
  170.   delwhile();          /* delete queue entry */
  171.   }
  172.  
  173. #ifdef STDO
  174. dodo() {
  175.   int      wq[4],top;
  176.   addwhile(wq);
  177.   postlabel(top = getlabel());
  178.   statement();
  179.   needtoken("while");
  180.   postlabel(wq[WQLOOP]);
  181.   test(wq[WQEXIT], YES);
  182.   jump(top);
  183.   postlabel(wq[WQEXIT]);
  184.   delwhile();
  185.   ns();
  186.   }
  187. #endif
  188.  
  189. #ifdef STFOR
  190. dofor() {
  191.   int wq[4],lab1,lab2;
  192.   addwhile(wq);
  193.   lab1 = getlabel();
  194.   lab2 = getlabel();
  195.   needtoken("(");
  196.   if(match(";") == 0) {
  197.     doexpr();
  198.     ns();            /* expr1 */
  199.     }
  200.   postlabel(lab1);
  201.   if(match(";") == 0) {
  202.     test(wq[WQEXIT], NO);   /* expr2 */
  203.     ns();
  204.     }
  205.   jump(lab2);
  206.   postlabel(wq[WQLOOP]);
  207.   if(match(")") == 0) {
  208.     doexpr();            /* expr3 */
  209.     needtoken(")");
  210.     }
  211.   jump(lab1);
  212.   postlabel(lab2);
  213.   statement();
  214.   jump(wq[WQLOOP]);
  215.   postlabel(wq[WQEXIT]);
  216.   delwhile();
  217.   }
  218. #endif
  219.  
  220. #ifdef STSWITCH
  221. doswitch() {
  222.   int wq[4],endlab,swact,swdef,*swnex,*swptr;
  223.   swact = swactive;
  224.   swdef = swdefault;
  225.   swnex = swptr = swnext;
  226.   addwhile(wq);
  227.   needtoken("(");
  228.   doexpr();            /* evaluate switch expression */
  229.   needtoken(")");
  230.   swdefault = 0;
  231.   swactive = 1;
  232.   jump(endlab = getlabel());
  233.   statement();            /* cases, etc */
  234.   jump(wq[WQEXIT]);
  235.   postlabel(endlab);
  236.   sw();             /* match cases */
  237.   while(swptr < swnext) {
  238.     defstorage(CINT>>2);
  239.     printlabel(*swptr++);   /* case label */
  240.     outbyte(',');
  241.     outdec(*swptr++);        /* case value */
  242.     nl();
  243.     }
  244.   defstorage(CINT>>2);
  245.   outdec(0);
  246.   nl();
  247.   if(swdefault) jump(swdefault);
  248.   postlabel(wq[WQEXIT]);
  249.   delwhile();
  250.   swnext = swnex;
  251.   swdefault = swdef;
  252.   swactive = swact;
  253.   }
  254.  
  255. docase() {
  256.   if(swactive == 0) error("not in switch");
  257.   if(swnext > swend) {
  258.     error("too many cases");
  259.     return;
  260.     }
  261.   postlabel(*swnext++ = getlabel());
  262.   constexpr(swnext++);
  263.   needtoken(":");
  264.   }
  265.  
  266. dodefault() {
  267.   if(swactive) {
  268.     if(swdefault) error("multiple defaults");
  269.       }
  270.   else error("not in switch");
  271.   needtoken(":");
  272.   postlabel(swdefault = getlabel());
  273.   }
  274. #endif
  275.  
  276. #ifdef STGOTO
  277. dogoto() {
  278.   if(nogo > 0)    error("not allowed with block-locals");
  279.   else noloc = 1;
  280.   if(symname(ssname, YES))  jump(addlabel());
  281.   else error("bad label");
  282.   ns();
  283.   }
  284.  
  285. dolabel() {
  286. char *savelptr;
  287.   blanks();
  288.   savelptr = lptr;
  289.   if(symname(ssname, YES)) {
  290.     if(gch() == ':') {
  291.       postlabel(addlabel());
  292.       return 1;
  293.       }
  294.     else bump(savelptr-lptr);
  295.     }
  296.   return 0;
  297.   }
  298.  
  299. addlabel() {
  300.   if(cptr = findloc(ssname)) {
  301.     if(cptr[IDENT] != LABEL) error("not a label");
  302.       }
  303.   else cptr = addsym(ssname,LABEL,LABEL,getlabel(),&locptr,LABEL);
  304.   return (getint(cptr+OFFSET, OFFSIZE));
  305.   }
  306. #endif
  307.  
  308. doreturn() {
  309.   if(endst() == 0) {
  310.     doexpr();
  311.     modstk(0, YES);
  312.     }
  313.   else modstk(0, NO);
  314.   ret();
  315.   }
  316.  
  317. dobreak() {
  318.   int *ptr;
  319.   if((ptr = readwhile()) == 0)    return;  /* no loops open */
  320.   modstk((ptr[WQSP]), NO);       /* clean up stack ptr  */
  321.   jump(ptr[WQEXIT]);           /* jump to exit label  */
  322.   }
  323.  
  324. docont() {
  325.   int *ptr;
  326.   if((ptr = readwhile()) == 0)    return;   /* no loops open */
  327.   modstk((ptr[WQSP]), NO);       /* clean up stack ptr  */
  328.   jump(wq[WQLOOP]);           /* jump to loop label  */
  329.   }
  330.  
  331. doasm() {
  332.   ccode = 0;        /* mark mode as "asm" */
  333.   while(1) {
  334.     inline();
  335.     if(match("#endasm")) break;
  336.     if(eof) break;
  337.     printf("%s\n",line);
  338.     }
  339.   kill();
  340.   ccode = 1;
  341.   }
  342.  
  343. stowlit(value, size) int value, size; {
  344.   if((litptr+size) >= LITMAX) {
  345.     printf("**** SMALL-C: literal queue overflow ****\n");
  346.     exit(-1);
  347.     }
  348.   putint(value, litq+litptr, size);
  349.   litptr=litptr+size;
  350.   }
  351.